package com.cicadasmall.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cicadasmall.common.base.BaseService;
import com.cicadasmall.common.base.LoginUser;
import com.cicadasmall.common.enums.UserTypeEnum;
import com.cicadasmall.common.func.Fn;
import com.cicadasmall.common.resp.R;
import com.cicadasmall.common.utils.ControllerUtil;
import com.cicadasmall.common.utils.SecurityUtils;
import com.cicadasmall.system.dto.UserInputDTO;
import com.cicadasmall.system.dto.UserQueryDTO;
import com.cicadasmall.system.dto.UserUpdateDTO;
import com.cicadasmall.data.domain.DeptDO;
import com.cicadasmall.data.domain.UserDO;
import com.cicadasmall.system.service.*;
import com.cicadasmall.system.vo.UserVO;
import com.cicadasmall.data.mapper.SysUserMapper;
import com.cicadasmall.system.wrapper.UserWrapper;
import lombok.AllArgsConstructor;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class UserServiceImpl extends BaseService<SysUserMapper, UserDO> implements IUserService {

    private final PasswordEncoder passwordEncoder;

    private final IUserRoleService userRoleService;

    private final IUserDeptService userDeptService;

    private final IDeptService deptService;

    private final IUserPositionService userPositionService;

    @Override
    public LoginUser login(String username) {

        UserDO user = getOne(getLambdaQueryWrapper().eq(UserDO::getUsername, username).or()
                .eq(UserDO::getEmail, username));

        if (Fn.isNull(user)) {
            throw new UsernameNotFoundException("用户不存在！");
        }

        user.setLastLoginIp(ControllerUtil.getClientIP());
        user.setLastLoginTime(LocalDate.now());
        user.setLoginNum(user.getLoginNum() + 1);
        updateById(user);

        return UserWrapper.newBuilder().loginUserDetails(user);
    }


    @Override
    public R changePassword(String oldPassword, String newPassword) {
        UserDO userDO = getById(SecurityUtils.getCurrentLoginUser().getUid());
        if (!passwordEncoder.matches(oldPassword, userDO.getPassword())) {
            return R.error("原密码错误", false);
        }
        userDO.setPassword(passwordEncoder.encode(newPassword));
        updateById(userDO);
        return R.ok(true);
    }

    @Override
    public R findById(Serializable uid) {
        UserVO userVo = UserWrapper.newBuilder().entityVO(getById(uid));
        userVo.setPassword(null);
        return R.ok(userVo);
    }


    @Override
    public R page(UserQueryDTO userQueryDTO) {
        LambdaQueryWrapper<UserDO> queryWrapper = getLambdaQueryWrapper()
                .eq(UserDO::getUserType, UserTypeEnum.系统.getCode());
        if (Fn.isNotEmpty(userQueryDTO.getUsername())) {
            queryWrapper.like(UserDO::getUsername, userQueryDTO.getUsername());
        }

        if (Fn.isNotEmpty(userQueryDTO.getPhone())) {
            queryWrapper.like(UserDO::getPhone, userQueryDTO.getPhone());
        }

        if (Fn.isNotNull(userQueryDTO.getStatus())) {
            queryWrapper.like(UserDO::getStatus, userQueryDTO.getStatus());
        }
        List<Integer> queryDeptIds = new ArrayList<>();
        if (Fn.isNotNull(userQueryDTO.getDeptId())) {
            queryDeptIds.add(userQueryDTO.getDeptId());
            List<DeptDO> childDeptList = deptService.findByParentId(userQueryDTO.getDeptId());
            if (Fn.isNotEmpty(childDeptList)) {
                queryDeptIds.addAll(childDeptList.stream().map(DeptDO::getDeptId).collect(Collectors.toList()));
            }
        }
        Page<UserDO> userPage = baseMapper.selectPageByDeptId(userQueryDTO.page(), queryDeptIds);

        return R.ok(UserWrapper.newBuilder().pageVO(userPage));
    }

    @Transactional
    @Override
    public R save(UserInputDTO userInputDTO) {
        UserDO user = userInputDTO.convertToEntity();
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setCreateIp(ControllerUtil.getClientIP());
        save(user);
        //Jin 更新角色信息
        userRoleService.updateUserRole(user.getUid(), userInputDTO.getRoleIdList());
        //Jin 更新部门信息
        userDeptService.updateUserDept(user.getUid(), userInputDTO.getDeptIdList());
        //Jin 更新职位信息
        userPositionService.updateUserPosition(user.getUid(), userInputDTO.getPostIdList());
        return R.ok(true);
    }

    @Transactional
    @Override
    public R update(UserUpdateDTO userUpdateDTO) {
        UserDO user = userUpdateDTO.convertToEntity();
        if (Fn.isNotEmpty(user.getPassword())) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        } else {
            user.setPassword(null);
        }
        updateById(user);
        //Jin 更新角色信息
        userRoleService.updateUserRole(user.getUid(), userUpdateDTO.getRoleIdList());
        //Jin 更新部门信息
        userDeptService.updateUserDept(user.getUid(), userUpdateDTO.getDeptIdList());
        //Jin 更新职位信息
        userPositionService.updateUserPosition(user.getUid(), userUpdateDTO.getPostIdList());
        return R.ok(true);
    }

    @Override
    public R deleteById(Serializable id) {
        baseMapper.deleteById(id);
        return R.ok(true);
    }
}
